#include "drv_SSD1306.h"
#include <string.h>
#include "rom_LcdFont.h"

#define OLED_IF_ROTATION 0
#define OLED_CMD 0  //д����
#define OLED_DATA 1 //д����

/* extern method */
extern void IIC_WRByte(uint8_t devAddr, uint8_t regAddr, uint8_t dat);
extern void OLED_Delay(uint32_t ms);

/* inside method */
static void OLED_WR_Byte(uint8_t dat, uint8_t cmd);

/* RAM resource */
static uint8_t GRAM[8][128];

static void OLED_WR_Byte(uint8_t dat, uint8_t cmd)
{
    const uint8_t OLED_DEV_ADDR = 0x78;
    cmd = (cmd == OLED_CMD) ? (0x00) : (0x40);
    IIC_WRByte(OLED_DEV_ADDR, cmd, dat);
}

void OLED_ColorTurn(uint8_t i)
{
	  if (i == 0) {
	  	  OLED_WR_Byte(0xA6, OLED_CMD);
	  }
	  if (i == 1) {
	  	  OLED_WR_Byte(0xA7, OLED_CMD);
	  }
}

void OLED_DisplayTurn(uint8_t i)
{
	  if (i == 0) {
	  	  OLED_WR_Byte(0xC8, OLED_CMD);
	  	  OLED_WR_Byte(0xA1, OLED_CMD);
	  }
	  if (i == 1) {
	  	  OLED_WR_Byte(0xC0, OLED_CMD);
	  	  OLED_WR_Byte(0xA0, OLED_CMD);
	  }
}


void OLED_DisPlay_On(void)
{
	  OLED_WR_Byte(0x8D, OLED_CMD);
	  OLED_WR_Byte(0x14, OLED_CMD);
	  OLED_WR_Byte(0xAF, OLED_CMD);
}

void OLED_DisPlay_Off(void)
{
	  OLED_WR_Byte(0x8D, OLED_CMD);
	  OLED_WR_Byte(0x10, OLED_CMD);
	  OLED_WR_Byte(0xAF, OLED_CMD);
}

void OLED_Refresh(void)
{
	  for (uint8_t i = 0; i < 8; i++) {
	  	  OLED_WR_Byte(0xb0 + i, OLED_CMD);
	  	  OLED_WR_Byte(0x02, OLED_CMD);
	  	  OLED_WR_Byte(0x10, OLED_CMD);
	  	  for (uint8_t n = 0; n < 128; n++) {
	  	  	  OLED_WR_Byte(GRAM[i][n], OLED_DATA);
	  	  }
	  }
}

void OLED_Clear(uint8_t tOn)
{
    memset(GRAM, tOn, sizeof(GRAM));
}

void OLED_Init(void)
{
    OLED_Delay(200);

    OLED_WR_Byte(0xAE, OLED_CMD); //--display off
    OLED_WR_Byte(0x02, OLED_CMD); //---set low column address
    OLED_WR_Byte(0x10, OLED_CMD); //---set high column address
    OLED_WR_Byte(0x40, OLED_CMD); //--set start line address
    OLED_WR_Byte(0xB0, OLED_CMD); //--set page address
    OLED_WR_Byte(0x81, OLED_CMD); // contract control
    OLED_WR_Byte(0xFF, OLED_CMD); //--128
    OLED_WR_Byte(0xA1, OLED_CMD); // set segment remap
    OLED_WR_Byte(0xA6, OLED_CMD); //--normal / reverse
    OLED_WR_Byte(0xA8, OLED_CMD); //--set multiplex ratio(1 to 64)
    OLED_WR_Byte(0x3F, OLED_CMD); //--1/32 duty
    OLED_WR_Byte(0xC8, OLED_CMD); // Com scan direction
    OLED_WR_Byte(0xD3, OLED_CMD); //-set display offset
    OLED_WR_Byte(0x00, OLED_CMD); //
    OLED_WR_Byte(0xD5, OLED_CMD); // set osc division
    OLED_WR_Byte(0x80, OLED_CMD); //
    OLED_WR_Byte(0xD8, OLED_CMD); // set area color mode off
    OLED_WR_Byte(0x05, OLED_CMD); //
    OLED_WR_Byte(0xD9, OLED_CMD); // Set Pre-Charge Period
    OLED_WR_Byte(0xF1, OLED_CMD); //
    OLED_WR_Byte(0xDA, OLED_CMD); // set com pin configuartion
    OLED_WR_Byte(0x12, OLED_CMD); //
    OLED_WR_Byte(0xDB, OLED_CMD); // set Vcomh
    OLED_WR_Byte(0x30, OLED_CMD); //
    OLED_WR_Byte(0x8D, OLED_CMD); // set charge pump enable
    OLED_WR_Byte(0x14, OLED_CMD); //
    OLED_WR_Byte(0xAF, OLED_CMD); //--turn on oled panel

    OLED_Clear(0xff);
		OLED_Refresh();
}

void LCD_DrawPoint(uint8_t x, uint8_t y, uint16_t color)
{
    x = (x <= 127 ? x : 127);
    y = (y <= 63 ? y : 63);

    GRAM[y / 8][x] |= 1 << y % 8;
}
